package framework.agent;

import framework.Message;
import framework.Trait;
import framework.server.Mail;
import framework.server.Server;
import framework.server.ServerException;
import framework.service.AbstractService;

public class Mailer extends AbstractService {

	public Mailer(Trait container, String agentName) {
		super(container, agentName);
	}

	@Override
	public void init() throws ServerException {
	}

	public static <M extends Message> M sendAndWait(Message message, String serviceName, String agentName, long waitPeriod) {
		return sendAndWait(new Mail(agentName, message), serviceName, agentName, waitPeriod);
	}

	public static <M extends Message> M sendAndWait(Mail mail, String serviceName, String agentName, long waitPeriod) {
		Mailer mailer = getMailer(agentName);
		mailer.sendMail(mail, serviceName);
		long sleep = 2L;
		while (null == (mail = mailer.pullMail())) {
			try {
				Thread.currentThread();
				Thread.sleep(sleep);
				if (sleep < 500L) {
					sleep *= 2L;
				}
			} catch (InterruptedException interruptedexception) { }
		}
		return mail.getMessage();
	}

	@Override
	protected Server getContainer() {
		return (Server) super.getContainer();
	}

	private void sendMail(Mail mail, String serviceName) {
		getContainer().sendMail(mail, serviceName);
	}

	private Mail pullMail() {
		return getContainer().pullMail(getServiceName());
	}

	private static Mailer getMailer(String agentName) {
		Server server = Server.getServer();
		Mailer mailer = server.getService(agentName);
		if (mailer == null) {
			mailer = new Mailer(server, agentName);
			mailer.starting();
			server.addService(mailer);
		}
		return mailer;
	}

}
